﻿using System;
using System.Xml;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace SAE_Jam
{
    public class SpriteAnimation
    {
        public Color color = Color.White;
        public Rectangle Source = new Rectangle(0, 0, 0, 0);

        public string Name { get; private set; }
        public Vector2 Position { get; set; }
        public int AnimationDelay { get; set; }

        private Texture2D atlas;
        private List<SpriteAnimationFrame> frames = new List<SpriteAnimationFrame>();

        private List<SpriteAnimationFrame> currentFrames;
        private int currentFrameCount = 0;
        private float timer = 0;

        public bool IsPlaying { get; private set; }

        public SpriteAnimation(string name, Texture2D atlas, string animationDataPath)
        {
            this.Name = name;
            this.atlas = atlas;
            this.IsPlaying = false;

            this.LoadFrames(animationDataPath);
        }

        public void Update(GameTime gameTime)
        {
            if (this.IsPlaying)
            {
                this.CalculateFrame(gameTime);
            }
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            if (this.IsPlaying)
            {
                Source = this.CalculateSource();
                spriteBatch.Draw(this.atlas, this.Position, Source, color);
            }
        }

        public void PlayAnimation(string animationName)
        {
            this.currentFrames = this.frames.FindAll((SpriteAnimationFrame animationFrame) => animationFrame.Name.Contains(animationName));
            this.IsPlaying = this.currentFrames.Count > 0 ? true : false;
        }

        private Rectangle CalculateSource()
        {
            SpriteAnimationFrame frame = currentFrames[currentFrameCount];
            return frame.Bounds;
        }

        private void CalculateFrame(GameTime gameTime)
        {
            this.timer += gameTime.ElapsedGameTime.Milliseconds;

            if (timer >= this.AnimationDelay)
            {
                this.timer = 0;

                if (this.currentFrameCount < this.currentFrames.Count - 1)
                {
                    this.currentFrameCount++;
                }
                else
                {
                    this.currentFrameCount = 0;
                }
            }
        }

        private void LoadFrames(string animationDataPath)
        {
            XmlReader xmlReader = XmlReader.Create(animationDataPath);

            while (xmlReader.Read())
            {
                if (xmlReader.IsStartElement("sprite"))
                {
                    string name = xmlReader.GetAttribute("n");

                    if (name.Contains(this.Name))
                    {
                        SpriteAnimationFrame animationFrame = new SpriteAnimationFrame();
                        animationFrame.Name = name;
                        animationFrame.Bounds.X = Convert.ToInt32(xmlReader.GetAttribute("x"));
                        animationFrame.Bounds.Y = Convert.ToInt32(xmlReader.GetAttribute("y"));
                        animationFrame.Bounds.Width = Convert.ToInt32(xmlReader.GetAttribute("w"));
                        animationFrame.Bounds.Height = Convert.ToInt32(xmlReader.GetAttribute("h"));

                        this.frames.Add(animationFrame);
                    }
                }
            }
        }
    }
}
